package services

import (
	"fmt"
	"github.com/goravel/framework/database/orm"
	"github.com/goravel/framework/facades"
	"github.com/spf13/cast"
	"goravel/app/models"
	"regexp"
	"strings"
)

var DetectModel map[string]map[string]any = map[string]map[string]any{
	"Equip clothes item violation detected": map[string]any{
		"title": "装备物品违规:超出互动范围",
		"item": map[string]any{
			"Container": "容器",
			"Distance":  "距离", //玩家位置
			"Item":      "物品", //Car_Repair_Kit_C
			"Location":  "位置", //C[Location: -898498.12, -103553.62, 36337.60]
		},
	},
	"Light item interact violation detected": map[string]any{
		"title": "检测到灯光项相互作用违规",
		"item": map[string]any{
			"Container": "容器",
			"Distance":  "距离", //玩家位置
			"Item":      "物品", //Car_Repair_Kit_C
			"Location":  "位置", //C[Location: -898498.12, -103553.62, 36337.60]
		},
	},
	"Request character action violation detected": map[string]any{
		"title": "请求字符操作冲突",
		"item": map[string]any{
			"Action":          "动作",
			"Desc":            "描述",
			"Distance":        "距离",
			"Server location": "服务器位置",
		},
	},
	"Ammo count violation detected for user": map[string]any{
		"title": "检测到用户的弹药计数违规",
		"item": map[string]any{
			"Weapon":   "武器",
			"Location": "位置",
		},
	},
	"Total violations detected for user": map[string]any{
		"title": "弹药计数违规总数|弹药计数违规",
		"item": map[string]any{
			"Count": "数量",
			"Type":  "类型",
		},
	},
	"Take damage violation detected": map[string]any{
		"title": "伤害违规",
		"item": map[string]any{
			"Attacker":                 "攻击者",
			"Weapon":                   "武器",
			"AttackerLoc":              "攻击者位置",
			"Victim":                   "受害者",
			"VictimLoc":                "受害者位置",
			"Victim location distance": "受害者位置距离",
		},
	},
	"AConZGameMode::KickPlayer:": map[string]any{
		"title": "踢人",
		"item": map[string]any{
			"Reason": "原因",
		},
	},
	"Add item to inventory violation detected": map[string]any{
		"title": "将商品添加到库存违规",
		"item": map[string]any{
			"Item":            "物品类型",
			"Location":        "玩家位置",
			"Distance":        "玩家距离",
			"Items container": "容器",
		},
	},
	"Take damage to base building element violation detected": map[string]any{
		"title": "对基础建筑元素的损坏违规",
		"item": map[string]any{
			"Attacker":   "攻击者",
			"Weapon":     "武器",
			"S[Location": "攻击者位置",
			"C[Location": "受害者位置",
			"Distance":   "距离", //Victim location distance
		},
	},
	"[FalseTrapTriggerViolation]": map[string]any{
		"title": "触发陷进（系统未检测到）",
		"item": map[string]any{
			"Prisoner":       "玩家",
			"triggered trap": "触发陷进",
		},
	},
	//	FalseTrapTriggerViolation：触发陷进（系统未检测到）
}

type MessageOptions struct {
	detectType map[string]string
}
type ViolationRule struct {
}

// 全局变量
var ruleMap = make(map[string]string)

// 前19个字符,日期时间
func (r *ViolationRule) GetActionTime(str string) string {
	return str[:19]
}

// playerName, playerId, playerStreamId
func (r *ViolationRule) GetPlayerInfo(str string) (string, string, string) {
	//#region 情况一：以User:开头，以,结尾，取中间的所有字符
	cond1 := false
	cond2 := false
	cond3 := false
	cond4 := false
	reg1 := regexp.MustCompile(`User:\s+(.*?)\)(\s*,|\s)`)
	strslice1 := reg1.FindStringSubmatch(str)
	if len(strslice1) > 1 {
		cond1 = true
	}
	cond2 = strings.Contains(str, "User id:")
	cond3 = strings.Contains(str, "Attacker:")
	if cond1 {
		playerTxt := strslice1[1] + ")"
		//去除前后空白
		playerTxt = strings.TrimSpace(playerTxt)
		splitSlice := strings.Split(playerTxt, "(")
		if len(splitSlice) < 2 {
			return "User:->（id,streamId）全部", "", ""
		}
		//处理玩家名字
		playerName := splitSlice[0]
		splitSlice[1] = "(" + splitSlice[1]
		reg2 := regexp.MustCompile(`\((.*?)\)`)
		playnameTxt := reg2.FindStringSubmatch(splitSlice[1])
		if len(playnameTxt) == 0 {
			return "User:->playerName", "", ""
		}
		playerIds := playnameTxt[1]
		ids := strings.Split(playerIds, ",")
		if len(ids) < 2 {
			return "User:->（id,streamId）分割", "", ""
		}
		playerName = strings.TrimSpace(playerName)
		playerId := strings.TrimSpace(ids[0])
		playerStreamId := strings.TrimSpace(ids[1])
		//其中任意一个为控制符时
		if playerId == "" || playerStreamId == "" || playerName == "" {
			fmt.Printf("playerName：%s, playerId：%s, playerStreamId：%s\n", playerName, playerId, playerStreamId)
		}
		return playerName, playerId, playerStreamId
	}
	if cond2 {
		otherSectionTxt := strings.Contains(str, "User id:")
		if otherSectionTxt {
			//情况二：以User id:开头，以,结尾，符号,0个或者1个，取中间的所有字符
			reg2 := regexp.MustCompile(`User id:\s+(.+?,|.*\S)`)
			//	找出所有的匹配
			strslice2 := reg2.FindAllStringSubmatch(str, -1)
			if len(strslice2) == 0 {
				return "User id:->(id,streamId)空", "", ""
			}
			//分为2种情况，第一中是没有逗号的，第二种是有逗号的
			if len(strslice2) == 1 {
				//没有逗号的情况
				playerTxt := strslice2[0][1]
				//正则取''之间的内容
				reg3 := regexp.MustCompile(`'([^']*)'`)
				strslice3 := reg3.FindStringSubmatch(playerTxt)
				if len(strslice3) == 0 {
					return "User id:->(id,streamId)无单引号", "", ""
				}
				playerTxt = strslice3[1]

				return "", "", playerTxt
			}
		}
	}
	if cond3 {
		reg3 := regexp.MustCompile(`Attacker:\s+(.*?)\),`)
		strslice3 := reg3.FindStringSubmatch(str)
		if len(strslice3) == 0 {
			return "Attacker:->(空)", "", ""
		}
		playerTxt := strslice3[1] + ")"
		//去除前后空白
		playerTxt = strings.TrimSpace(playerTxt)
		splitSlice := strings.Split(playerTxt, "(")
		if len(splitSlice) < 2 {
			return "Attacker:->(id,streamId)空", "", ""
		}
		//处理玩家id
		playerName := splitSlice[0]
		idStr := "(" + splitSlice[1]
		reg2 := regexp.MustCompile(`\((.*?)\)`)
		playidTxt := reg2.FindStringSubmatch(idStr)
		if len(playidTxt) == 0 {
			return "Attacker:->(id,streamId)括号内", "", ""
		}

		ids := strings.Split(playidTxt[1], ",")
		if len(ids) < 2 {
			return "Attacker:->(id,streamId)逗号分割", "", ""
		}
		playerName = strings.TrimSpace(playerName)
		playerId := strings.TrimSpace(ids[0])
		playerStreamId := strings.TrimSpace(ids[1])
		//其中任意一个为控制符时
		if playerId == "" || playerStreamId == "" || playerName == "" {
			fmt.Printf("playerName：%s, playerId：%s, playerStreamId：%s\n", playerName, playerId, playerStreamId)
		}
		return playerName, playerId, playerStreamId
	}
	//按单词匹配字符：Prisoner
	reg4 := regexp.MustCompile(`Prisoner`)
	strslice4 := reg4.FindStringSubmatch(str)
	if len(strslice4) > 0 {
		cond4 = true
	}
	if cond4 {
		reg5 := regexp.MustCompile(`Prisoner\s+(.*?)triggered trap`)
		strslice5 := reg5.FindStringSubmatch(str)
		if len(strslice5) == 0 {
			return "Prisoner(.*?)triggered trap之间", "", ""
		}
		playerTxt := strslice5[1]
		//按照:分割
		splitSlice := strings.Split(playerTxt, ":")
		playerName := strings.TrimSpace(splitSlice[0])
		playerStreamId := strings.TrimSpace(splitSlice[1])
		//其中任意一个为控制符时
		if playerStreamId == "" || playerName == "" {
			fmt.Printf("playerName：%s, playerStreamId：%s\n", playerName, playerStreamId)
		}
		return playerName, "", playerStreamId
	}

	return "空", "空", "空"
}

/*
*
ViolationType
Distance
Level
Amount
Objects
Container
PlayerArea
ServerArea
PlayerLocation
TargetLocation
OriginalText
*/
func (r *ViolationRule) GetViolationParse(str string, id uint) string {
	for k, v := range DetectModel {
		if strings.Contains(str, k) {
			//1、定义变量
			var violation models.ViolationLog
			violation.ViolationType = v["title"].(string)
			userName, userId, streamId := r.GetPlayerInfo(str)
			violation.UserName = userName
			violation.UserId = cast.ToInt(userId)
			violation.StreamId = streamId
			violation.OriginalText = str
			for k1, _ := range v["item"].(map[string]any) {
				//fmt.Printf("%s：%s\n", k1, v1)
				r.handleFields(k, k1, &violation, str)
			}
			violation.ConfigurationID = cast.ToInt(id)
			err := facades.Orm().Query().
				Where("original_text", violation.OriginalText).
				FirstOrFail(&violation)
			if err == orm.ErrRecordNotFound {
				facades.Orm().Query().Create(&violation)
			}
		} else {
			continue
		}
	}
	return ""
}
func (r *ViolationRule) handleFields(pk string, key string, violation *models.ViolationLog, originStr string) {
	violation.ActionTime = r.GetActionTime(originStr)
	//如果key包含了这些字段，就赋值
	if strings.Contains(originStr, pk) && strings.Contains(key, "Container") {
		//正则获取Container:开头的,结尾的字符
		regCont := regexp.MustCompile(`Container:\s*(.*?),`)
		strslice1 := regCont.FindStringSubmatch(originStr)
		if len(strslice1) > 0 {
			violation.Container = strslice1[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Distance") {
		regDist := regexp.MustCompile(`Distance:\s*(.*)`)
		strslice2 := regDist.FindStringSubmatch(originStr)
		if len(strslice2) > 0 {
			violation.Distance = strslice2[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Item") {
		regItem := regexp.MustCompile(`Item:\s*(.*?),`)
		strslice3 := regItem.FindStringSubmatch(originStr)
		if len(strslice3) > 0 {
			violation.Item = strslice3[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Location") {
		//可能有逗号，或者没有逗号都匹配
		regLoc := regexp.MustCompile(`Location:\s*(.*,|.*)`)
		strslice4 := regLoc.FindStringSubmatch(originStr)
		if len(strslice4) > 0 {
			violation.Location = strslice4[1]
		}

	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Action") {
		regAct := regexp.MustCompile(`Action:\s*(.*?),`)
		strslice5 := regAct.FindStringSubmatch(originStr)
		if len(strslice5) > 0 {
			violation.ActionTxt = strslice5[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Desc") {
		regDesc := regexp.MustCompile(`Desc:\s*(.*?),`)
		strslice6 := regDesc.FindStringSubmatch(originStr)
		if len(strslice6) > 0 {
			violation.DescTxt = strslice6[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Server location") {
		regServerLoc := regexp.MustCompile(`Server location:\s+(.*?),`)
		strslice7 := regServerLoc.FindStringSubmatch(originStr)
		if len(strslice7) > 0 {
			violation.ServerLocation = strslice7[1]
		}
	}
	//差一个Client location
	if strings.Contains(originStr, pk) && strings.Contains(key, "Weapon") {
		regWeapon := regexp.MustCompile(`Weapon:\s+(.*?),`)
		strslice8 := regWeapon.FindStringSubmatch(originStr)
		if len(strslice8) > 0 {
			violation.Weapon = strslice8[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Count") {
		regCount := regexp.MustCompile(`Count:\s+(.*)`)
		strslice9 := regCount.FindStringSubmatch(originStr)
		if len(strslice9) > 0 {
			violation.CountTxt = strslice9[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Attacker") {
		regAttacker := regexp.MustCompile(`Attacker:\s*(.*?),`)
		strslice10 := regAttacker.FindStringSubmatch(originStr)
		if len(strslice10) > 0 {
			violation.Attacker = strslice10[1]
		}

	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "AttackerLoc") {
		regAttackerLoc := regexp.MustCompile(`S\[AttackerLoc :(.*?)VictimLoc:`)
		strslice11 := regAttackerLoc.FindStringSubmatch(originStr)
		if len(strslice11) > 0 {
			violation.AttackerLoc = strslice11[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Victim") {
		regVictim := regexp.MustCompile(`Victim:\s*(.*?),`)
		strslice12 := regVictim.FindStringSubmatch(originStr)
		if len(strslice12) > 0 {
			violation.Victim = strslice12[1]
		}
	}
	//这里的逻辑不知道
	if strings.Contains(originStr, pk) && strings.Contains(key, "VictimLoc") {
		regVictimLoc := regexp.MustCompile(`VictimLoc:\s*(.*),`)
		strslice13 := regVictimLoc.FindStringSubmatch(originStr)
		if len(strslice13) > 0 {
			violation.VictimLoc = strslice13[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "VictimLocationDistance") {
		regVictimLocDist := regexp.MustCompile(`VictimLocationDistance:\s*(.*?),`)
		strslice14 := regVictimLocDist.FindStringSubmatch(originStr)
		if len(strslice14) > 0 {
			violation.VictimLocationDistance = strslice14[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Reason") {
		//获取Reason:开头的,后面的所有字符
		regReason := regexp.MustCompile(`Reason:\s*(.*)`)
		strslice15 := regReason.FindStringSubmatch(originStr)
		if len(strslice15) > 0 {
			violation.Reason = strslice15[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Items container") {
		regItemsContainer := regexp.MustCompile(`Items container:\s*(.*?),`)
		strslice16 := regItemsContainer.FindStringSubmatch(originStr)
		if len(strslice16) > 0 {
			violation.ItemsContainer = strslice16[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "Prisoner") {
		regPrisoner := regexp.MustCompile(`Prisoner (.*?)\s`)
		strslice17 := regPrisoner.FindStringSubmatch(originStr)
		if len(strslice17) > 0 {
			violation.Prisoner = strslice17[1]
		}
	}
	if strings.Contains(originStr, pk) && strings.Contains(key, "TriggeredTrap") {
		regTriggeredTrap := regexp.MustCompile(`triggered trap\((.*?)\)`)
		strslice18 := regTriggeredTrap.FindStringSubmatch(originStr)
		if len(strslice18) > 0 {
			violation.TriggeredTrap = strslice18[1]
		}
	}
}

// 第一步：关键字条件检测
func (r *ViolationRule) getViolationStepOne(str string) map[string]string {
	//初始化ruleMap
	//情况一：正则匹配，取:Equip clothes item violation detected ->之后的所有字符
	reg1 := regexp.MustCompile(`Add item to inventory violation detected -> (.*)`)
	strslice1 := reg1.FindAllStringSubmatch(str, -1)
	if len(strslice1) > 0 {
		//穷举所有关键词-》正则获取单词加:开头的所有字符
		reg2 := regexp.MustCompile(`(\w+):\s+`)
		strslice2 := reg2.FindAllStringSubmatch(strslice1[0][1], -1)
		if len(strslice2) > 0 {
			//追加到map中
			for _, v := range strslice2 {
				//如果ruleMap中没有这个key，就添加，否则不添加
				if _, ok := ruleMap[v[1]]; !ok {
					ruleMap[v[1]] = v[1]
				} else {
					continue
				}
			}
		}
	}
	fmt.Println(ruleMap)
	return ruleMap
}
